﻿using System;
using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Utils;
using ImageEffects;
using UnityEngine;
using Yoozoo.Gameplay.RTS;
using Yoozoo.Libs;
using Yoozoo.Managers;
using Random = System.Random;

namespace Gameplay.PVE.Survivor
{
    public class GpuModelRenderer: ModelRenderer
    {
        private ModelInstancingGroup modelGroup;
        private ModelInstaning model;
        private BattleUnit unit;
        private bool isMoving;
        private string currentAction;
        private bool isShooting;
        private Transform transform;

        private GameObject debugCube;
        
        private static float shadowAlpha = 1;
        
        public void Initialize(BattleUnit unit,ModelInstancingGroup modelGroup)
        {
            this.transform = modelGroup.transform;
            this.unit = unit;
            this.modelGroup = modelGroup;
            model = modelGroup.modelInstancing;
            model.Init();
            var instanceId = model.SetConfig(model.poolKey, 100000, 1,modelGroup.animationInfo);
            model.SetMainColor(instanceId,Color.white);
            model.SetScale(model.localScale, true);
            
            model.SetPosition(unit.position);
            model.SetForward(unit.Forward);
            model.SetAnimatorEnabled(true);
            model.SetRendererEnabled(true);
            model.SetAnimatorSpeed(speed);
            model.SetRimColor(Color.white);
            model.SetDissolve(0);
            model.SetShadowAlpha(shadowAlpha);
            LightController.AddGpuSkinningMaterial(BattleConstValue.LightElementMark,model.poolKey);
            /*debugCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
            debugCube.transform.localScale = new Vector3(0.3f,0.3f,0.3f);
            debugCube.transform.SetParent(modelGroup.transform);
            debugCube.transform.localPosition = Vector3.zero;
            debugCube.transform.localEulerAngles = Vector3.zero;*/
            
            modelGroup.Initialize();
            unit.gunPoints = modelGroup.GetGunPoints();
            if (unit.gunPoints != null)
            {
                if (unit.gunPoints.Count > 1)
                {
                    unit.gunPoint = unit.gunPoints[1];
                }
                else
                {
                    unit.gunPoint = unit.gunPoints[0];
                }

                if (unit.gunPoint == null)
                {
                    unit.gunPoint = unit.AimPoint;
                }
            }
            
            isMoving = false;
            currentAction = "Idle";
            UpdateMovingState();
        }

        public void SetForward(Vector3 forward)
        {
            model?.SetForward(forward);
        }

        public override void Update()
        {
            base.Update();
            transform.forward = unit.Forward;
            var height = transform.position.y;
            model?.SetShadowHeight(height);
            for (int i = 0; i < modelGroup.modelGpuInstancingList.Count; i++)
            {
                var gpuInstance = modelGroup.modelGpuInstancingList[i];
                gpuInstance.SetShadowHeight(height);
            }
        }

        public void HideWeapon(int index)
        {
            if (modelGroup.modelGpuInstancingList.Count > index)
            {
                modelGroup.modelGpuInstancingList[index].OnRelease();
            }
        }
        
        public override void Play(string animName,bool isFullBody = false,bool resetTransition = true)
        {
            InternalSetTrigger(animName,resetTransition);
            UpdateMovingState();
        }

        private void InternalSetTrigger(string name, bool resetTransition = false)
        {
            if (BattleDebug.enableLog)
            {
                BattleDebug.Log(Time.time + " " + unit.unitId + " GpuAnimation " + name);
            }
            model?.SetTrigger(name, resetTransition);
            currentAction = name;
        }

        private void UpdateMovingState()
        {
            if (this.currentAction == "Idle" || this.currentAction == "Run")
            {
                if (isMoving)
                {
                    InternalSetTrigger("Run");
                }
                else
                {
                    InternalSetTrigger("Idle");
                }
            }
            /*else if (currentAction == "Fire")
            {
                var currentTime = model.CurrentTime;
                if (!isMoving)
                {
                    model.SetTrigger("Fire");
                }
                else
                {
                    model.SetTrigger("MoveFire");
                }
                if (this.currentAction == "Fire")
                {
                    model.SetAnimatorTime(currentTime);
                }
            }*/
        }
        
        public void SetMoving(bool isMoving)
        {
            this.isMoving = isMoving;
            UpdateMovingState();
        }

        public override void Dispose()
        {
            if (modelGroup != null)
            {
                modelGroup.Dispose();
                model?.OnRelease();
                model = null;
            }
            modelGroup = null;
            isDissolving = false;
        }

        public bool isDissolving = false;

        public void StartDissolve()
        {
            for (int i = 0; i < modelGroup.modelGpuInstancingList.Count; i++)
            {
                var gpuInstance = modelGroup.modelGpuInstancingList[i];
                gpuInstance.OnRelease();
            }
            model?.HideShadow();
            isDissolving = true;
        }
        
        public void SetDissolveAmount(float amount)
        {
            model?.SetDissolve(amount);
            amount = 1 - amount * 2;
            if (amount < 0)
            {
                amount = 0;
            }
            model?.SetShadowAlpha(shadowAlpha * amount);
        }
        
        public override void SetAnimatorSpeed(float speed)
        {
            this.speed = speed;
            model?.SetAnimatorSpeed(speed);
        }
        
        public override void SetFlashAmount(float amount)
        {
            model?.SetRimValue(amount);
        }
    }
}
